package a

import (
	"encoding/json"
	"strings"
	"time"

	"gorm.io/gorm"
)

// 示例1：生成2024年2月（闰年）的日期
// days202402 := A予月日期组(2024, 2)
// 输出：[01 02 03 ... 29]（共29天）
// 生成指定年月的日期切片（格式："01"-"31"）
func A予月日期组(year, month int) []string {
	var days []string
	// 获取当月第一天
	firstDay := time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.UTC)
	// 遍历当月所有日期（通过加1天直到月份变化）
	for d := firstDay; d.Month() == time.Month(month); d = d.AddDate(0, 0, 1) {
		days = append(days, d.Format("02")) // "02" 确保单数日期前补零（如01、09）
	}
	return days
}

// A时间筛选req 时间筛选参数
// A时间: 时间条件（支持 "today"/"yesterday"/"2025-11-12-2025-11-13"/"[1762924800,1763011200]"）
// A时间字段: 筛选的时间字段（如 "pay_time"/"create_time"，默认 "add_time"）
type A时间筛选req struct {
	A时间   string
	A时间字段 string
}

// A时间筛选 通用时间筛选工具函数（所有 Model 均可直接调用）
func A时间筛选(tx *gorm.DB, param *A时间筛选req) *gorm.DB {
	// 处理默认值
	timeKey := param.A时间字段
	if timeKey == "" {
		timeKey = "add_time"
	}
	if param.A时间 == "" {
		return tx
	}

	var startTime, endTime int64

	// 1. 数组类型时间（[起始时间戳, 结束时间戳]）
	switch {
	case strings.HasPrefix(param.A时间, "[") && strings.HasSuffix(param.A时间, "]"):
		var arr []int64
		if err := json.Unmarshal([]byte(param.A时间), &arr); err == nil && len(arr) >= 2 {
			startTime = arr[0]
			endTime = arr[1]
			// 当天结束时间补全为 23:59:59
			if startTime == endTime || endTime == time.Unix(endTime, 0).Truncate(24*time.Hour).Unix() {
				endTime += 86399
			}
		}

	// 2. 固定时间类型（today/yesterday/week 等）
	case isFixedTimeType(param.A时间):
		startTime, endTime = getFixedTimeRange(param.A时间)

	// 3. 日期范围字符串（格式："2025-11-12-2025-11-13" 或 "2025-11-12 00:00:00-2025-11-13 23:59:59"）
	case strings.Contains(param.A时间, "-"):
		startTime, endTime = parseDateRange(param.A时间)
	}

	// 拼接时间查询条件
	if startTime != 0 && endTime != 0 {
		tx = tx.Where(timeKey+" >= ? AND "+timeKey+" <= ?", startTime, endTime)
	} else if startTime != 0 {
		tx = tx.Where(timeKey+" >= ?", startTime)
	} else if endTime != 0 {
		tx = tx.Where(timeKey+" < ?", endTime)
	}

	return tx
}

// isFixedTimeType 判断是否为固定时间类型
func isFixedTimeType(timeParam string) bool {
	fixedTypes := []string{
		"today", "yesterday", "week", "month", "year",
		"last week", "last month", "last year", "quarter",
		"lately7", "lately30",
	}
	for _, t := range fixedTypes {
		if timeParam == t {
			return true
		}
	}
	return false
}

// getFixedTimeRange 计算固定时间类型的时间戳范围（完全对齐 PHP 逻辑）
func getFixedTimeRange(timeParam string) (startTime, endTime int64) {
	now := time.Now()
	switch timeParam {
	case "today":
		startTime = now.Truncate(24 * time.Hour).Unix() // 今日 00:00:00
		endTime = startTime + 86399                     // 今日 23:59:59
	case "yesterday":
		startTime = now.AddDate(0, 0, -1).Truncate(24 * time.Hour).Unix() // 昨日 00:00:00
		endTime = startTime + 86399                                       // 昨日 23:59:59
	case "week":
		weekDay := int(now.Weekday())
		if weekDay == 0 {
			weekDay = 7 // 周日转为 7（周一为一周起始）
		}
		startTime = now.AddDate(0, 0, -weekDay+1).Truncate(24 * time.Hour).Unix() // 周一 00:00
		endTime = startTime + 6*86400 + 86399                                     // 周日 23:59
	case "month":
		year, month, _ := now.Date()
		startTime = time.Date(year, month, 1, 0, 0, 0, 0, time.Local).Unix()    // 本月1日 00:00
		endTime = time.Date(year, month+1, 0, 23, 59, 59, 0, time.Local).Unix() // 本月最后一天 23:59
	case "year":
		year := now.Year()
		startTime = time.Date(year, 1, 1, 0, 0, 0, 0, time.Local).Unix()    // 本年1月1日 00:00
		endTime = time.Date(year, 12, 31, 23, 59, 59, 0, time.Local).Unix() // 本年12月31日 23:59
	case "last week":
		weekDay := int(now.Weekday())
		if weekDay == 0 {
			weekDay = 7
		}
		startTime = now.AddDate(0, 0, -weekDay-6).Truncate(24 * time.Hour).Unix() // 上周一开始 00:00
		endTime = startTime + 6*86400 + 86399                                     // 上周末 23:59
	case "last month":
		year, month, _ := now.Date()
		lastMonth := month - 1
		if lastMonth == 0 {
			lastMonth = 12
			year--
		}
		startTime = time.Date(year, lastMonth, 1, 0, 0, 0, 0, time.Local).Unix() // 上月1日 00:00
		endTime = time.Date(year, month, 0, 23, 59, 59, 0, time.Local).Unix()    // 上月最后一天 23:59
	case "last year":
		year := now.Year() - 1
		startTime = time.Date(year, 1, 1, 0, 0, 0, 0, time.Local).Unix()    // 上年1月1日 00:00
		endTime = time.Date(year, 12, 31, 23, 59, 59, 0, time.Local).Unix() // 上年12月31日 23:59
	case "quarter":
		year, month, _ := now.Date()
		quarter := (int(month)-1)/3 + 1
		startMonth := (quarter-1)*3 + 1
		endMonth := startMonth + 2
		startTime = time.Date(year, time.Month(startMonth), 1, 0, 0, 0, 0, time.Local).Unix()  // 本季度第一天 00:00
		endTime = time.Date(year, time.Month(endMonth)+1, 0, 23, 59, 59, 0, time.Local).Unix() // 本季度最后一天 23:59
	case "lately7":
		startTime = now.Add(-7 * 24 * time.Hour).Unix() // 最近7天（当前时间往前推7天）
		endTime = now.Unix()
	case "lately30":
		startTime = now.Add(-30 * 24 * time.Hour).Unix() // 最近30天
		endTime = now.Unix()
	}
	return
}

// parseDateRange 解析日期范围字符串
func parseDateRange(timeStr string) (startTime, endTime int64) {
	parts := strings.SplitN(timeStr, "-", 2)
	if len(parts) != 2 {
		return
	}
	startStr := strings.TrimSpace(parts[0])
	endStr := strings.TrimSpace(parts[1])

	// 解析起始时间
	if startStr != "" {
		// 尝试解析 "2025-11-12 00:00:00" 格式
		if t, err := time.ParseInLocation("2006-01-02 15:04:05", startStr, time.Local); err == nil {
			startTime = t.Unix()
		} else if t, err := time.ParseInLocation("2006-01-02", startStr, time.Local); err == nil {
			startTime = t.Unix() // 仅日期默认 00:00:00
		}
	}

	// 解析结束时间
	if endStr != "" {
		// 尝试解析 "2025-11-13 23:59:59" 格式
		if t, err := time.ParseInLocation("2006-01-02 15:04:05", endStr, time.Local); err == nil {
			endTime = t.Unix()
		} else if t, err := time.ParseInLocation("2006-01-02", endStr, time.Local); err == nil {
			endTime = t.Unix() + 86399 // 仅日期默认 23:59:59
		}
	}

	// 补全当天结束时间（如果起始和结束是同一天）
	if startTime != 0 && endTime != 0 {
		if startTime == endTime || endTime == time.Unix(endTime, 0).Truncate(24*time.Hour).Unix() {
			endTime += 86399
		}
	} else if endTime != 0 {
		// 只有结束时间：小于次日 00:00:00
		endTime += 86400
	}

	return
}
